import { Color } from "@/contrib"
import { addConstructionSite, planSite } from "@/contrib/construction"
import { goToDropPos } from "@/contrib/creep/harvester"
import { HarvestMode } from "@/role/base/harvester"
import { CreepRole, RoleDatas } from "@/role/types/role"
import { serializePos } from "@/utils"
import CreepController from "../controller"


class RoleHarvester {

    /**
     *
     * @param creep
     * @returns
     */
    static loop(creep: Creep) {

        if (creep.ticksToLive < 5) {
            creep.drop(RESOURCE_ENERGY)
        }

        const memoryData: RoleDatas[CreepRole.Harvester] = creep.memory.data as RoleDatas[CreepRole.Harvester]

        if (!memoryData) {
            creep.log('memory error')
            return
        }

        let source: Source
        if (!memoryData.sourceId) {
            source = CreepController.harvesterFindSource(creep)
        }

        if (memoryData.sourceId) {
            source = Game.getObjectById(memoryData.sourceId)
        }

        if (!source) {
            return
        }

        // const source = CreepController.harvesterFindSource(creep)
        // if (!source) {
        //     return
        // }
        // source.room.memory.source[source.id].creepId = creep.id

        // 如果是新source
        // 设置dropPos
        // 搭建container的constructionSite
        // 等待build
        if (!source.room.memory.source[source.id].dropped) {
            const { targetPos, range } = goToDropPos(creep, source)
            // 没有抵达位置就准备未完成
            if (!creep.pos.inRangeTo(targetPos, range)) return false
            // 启动模式下，走到之后就将其设置为能量丢弃点
            source.setDroppedPos(creep.pos)
            // 把该位置存缓存到自己内存
            creep.memory.data['standPos'] = serializePos(creep.pos)

            // 如果脚下没有 container 及工地的话就放工地并发布建造任务
            const getContainerFilter = s => s.structureType === STRUCTURE_CONTAINER
            const posContinaer = creep.pos.lookFor(LOOK_STRUCTURES).filter(getContainerFilter)
            const posContinaerSite = creep.pos.lookFor(LOOK_CONSTRUCTION_SITES).filter(getContainerFilter)

            if (posContinaer.length <= 0 && posContinaerSite.length <= 0) {
                const { x, y, roomName } = creep.pos
                addConstructionSite([{ x, y, roomName, type: STRUCTURE_CONTAINER }])
                //
                // 直接设置constructionSite
                // 放置正在排队的工地
                planSite()
                // container 建造任务的优先级应该是最高的
                // creep.room.work.addTask({ type: WorkTaskType.BuildStartContainer, sourceId: source.id, priority: 4 })
                creep.log(`发布 source ${source.id} 的 container 建造任务`, Color.Green)
            }
        }

        // // 靠近 upgrader 的 harvester free to upgrade
        if (source.energy == 0 && creep.pos.isNearTo(creep.room.controller.pos)) {
            // 优先 upgrader
            if (creep.store[RESOURCE_ENERGY] == 0) {
                if (!creep.memory.targetId) {
                    if (creep.room.memory.upgradeLinkId) {
                        const link = Game.getObjectById(creep.room.memory.upgradeLinkId) as StructureLink
                        if (link && link.store[RESOURCE_ENERGY] > 0) {
                            creep.memory.targetId = link.id
                        }
                    }
                }
                if (creep.memory.targetId) {
                    const storeObj = Game.getObjectById(creep.memory.targetId) as StructureWithStore
                    if (storeObj) {
                        const status = creep.withdraw(storeObj, RESOURCE_ENERGY)
                        if (status == ERR_NOT_ENOUGH_ENERGY || status == OK) {
                            delete creep.memory.targetId
                        }
                        return
                    }
                    creep.say('need Energy')
                }
            }
            else {
                const status = creep.upgradeController(creep.room.controller)
                if (status != OK && status != ERR_NOT_IN_RANGE) {
                    creep.say('U->error')
                }
            }
        }

        if (memoryData.sourceId) {

            if (Game.time % 2) {

                if (creep.store[RESOURCE_ENERGY] >= 10) {
                    // harvester repair container
                    const container = creep.pos.lookFor(LOOK_STRUCTURES).find(s => {
                        return s.structureType === STRUCTURE_CONTAINER
                    }) as StructureContainer
                    if (container && container.hits < container.hitsMax) {
                        memoryData.targetId = container.id
                    }
                }
            }

            if (memoryData.targetId) {
                const target = Game.getObjectById(memoryData.targetId)
                if (creep.store[RESOURCE_ENERGY] == 0 || !target || target.hits >= target.hitsMax) {
                    delete memoryData.targetId
                }
                const status = creep.repair(target)
            }

            if (source) {

                if (creep.store.getFreeCapacity(RESOURCE_ENERGY) == 0) {
                    const target = source.getLink()
                    if (target) {
                        if (target.store.getFreeCapacity(RESOURCE_ENERGY) > 0) {
                            const status = creep.transfer(target, RESOURCE_ENERGY)
                            console.log(creep.name, target.id, status)
                            return
                        }
                    }
                }

                const status = creep.harvest(source)
                goToDropPos(creep, source)
                if (status == OK) {
                    creep.memory.stand = true
                }
            }
        }
    }
}

export default RoleHarvester
